package com.Cfeng.XiaohuanChat.filter;

import com.Cfeng.XiaohuanChat.domain.CaptchaCodeVo;
import com.Cfeng.XiaohuanChat.domain.KaptchaConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.filter.OncePerRequestFilter;
import org.thymeleaf.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Cfeng
 * @date 2022/8/21
 * 配置kaptcha验证过滤器，在security框架的username过滤器之前执行
 */
@Component //这里不使用普通的过滤器注解，直接component即可
@RequiredArgsConstructor
@Slf4j
public class KaptchaCodeFilter extends OncePerRequestFilter {

    //需要使用securtiy的验证失败的处理器来进行处理
    private final AuthenticationFailureHandler authenticationFailureHandler;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        String uri = request.getServletPath();
        //post登录提交的位置
        if("/authentication/form".equals(uri) && request.getMethod().equalsIgnoreCase("post")) {
            //用户输入的验证码
            String captchaInRequest = request.getParameter("captchaCode").trim();
            //session中的
            CaptchaCodeVo captchaInSession = (CaptchaCodeVo)request.getSession().getAttribute(KaptchaConstant.CAPTCHA_SESSION_KEY);
            //校验失败之后调用spring security的校验失败的处理器
            try {
                if(StringUtils.isEmpty(captchaInRequest)) {
                    throw new SessionAuthenticationException("验证码不能为空");
                }
                if(captchaInSession == null) {
                    throw  new SessionAuthenticationException("验证码不存在");
                }
                if(captchaInSession.isExpired()) {
                    //从用户session中删除
                    request.getSession().removeAttribute(KaptchaConstant.CAPTCHA_SESSION_KEY);
                    throw new SessionAuthenticationException("验证码已过期");
                }
                if(! captchaInRequest.equalsIgnoreCase(captchaInSession.getCode())) {
                    throw new SessionAuthenticationException("验证码错误");
                }
            } catch (SessionAuthenticationException e) {
                //调用失败处理器，不再执行
//                authenticationFailureHandler.onAuthenticationFailure(request,response,e);
                //退出不放行
                log.error(e.getMessage());
                authenticationFailureHandler.onAuthenticationFailure(request,response, e);
                return;
            }
        }
        filterChain.doFilter(request,response);
    }
}
